'use strict';
let panels_ns = new function() {
	let { screenSize } = global_ns;
	let { Node, Spatial } = nodes_ns;
	let { Value } = value_ns;
	let { Process } = process_ns;
	
	
	let drawText = (text, ctx, pos, size) => {
		let lines = text.split('\n');
		
		let m = ctx.measureText(text);
		let w = Math.abs(m.actualBoundingBoxLeft) + Math.abs(m.actualBoundingBoxRight);
		
		for(let i = 0; i < lines.length; i++) {
			ctx.fillText(lines[i], pos.x, pos.y+i*14);
		};
	};
	
	
	let DataNode = this.DataNode = class extends EventEmitter {
		constructor(data) {
			super();
			
			this.input = new Value(0);
			this.output = new Value(0);
			
			let api = { std: {} };
			Object.defineProperty(api.std, 'in', {
				get: () => this.input.value,
				enumerable: true, configurable: true
			});
			
			Object.defineProperty(api.std, 'out', {
				get: () => this.output.value,
				set: v => this.output.value = v,
				enumerable: true, configurable: true
			});
			
			if(typeof data !== 'function') throw Error('data is not a function');
			
			this.inter = new Process({
				code: data,
				api: api
			});
		}
		
		set stdin(v) {
			this.input.new(v);
		//	this.inter.emit('stdin');
		}
		get stdin() { return this.input; }
		
		set stdout(v) { this.output.value = v; }
		get stdout() { return this.output; }
		
		bind(node) {
			this.stdin = node.stdout;
			global_ns.binder.emit('stdin');
		//	this.inter.emit('stdin');
			return node;
		}
		
		// TODO: временно, потом убрать
		log(n) {
			console.log(n, this.input.value, this.inter.value, this.output.value);
		}
	};
	
	
	let Panel = this.Panel = class extends Spatial {
		constructor(p = {}) {
			super(p);
			
			this._size = (p.size || vec2()).buf();
			this.title = p.title||'Title';
			
			this.style = Object.assign({
				padding: vec2(10, 10),
				borderColor: '#cccccc',
				background: '#223344',
				shadowBlur: 5,
				shadowColor: '#000000',
				shadowOffset: vec2(3, 5)
			}, p.style || {});
		}
		
		get size() { return this._size; }
		get globalSize() { return this.globalScale.inc(this._size); }
		
		draw(ctx) {
			let style = this.style;
			let pos = this.globalPosition, size = this.globalSize;
			
			ctx.save();
			ctx.rotateOffset(this.globalRotation, pos);
			
			ctx.fillStyle = style.background;
			ctx.strokeStyle = style.borderColor;
			ctx.shadowOffsetX = style.shadowOffset.x;
			ctx.shadowOffsetY = style.shadowOffset.y;
			ctx.shadowColor = style.shadowColor;
			ctx.shadowBlur = style.shadowBlur;
			
			ctx.fillRect(pos.x, pos.y, size.x, size.y);
			
			ctx.shadowColor = 'transparent';
			ctx.strokeRect(pos.x, pos.y, size.x, size.y);
			ctx.restore();
		}
	};
	
	
	let PanelViewer = this.PanelViewer = class extends Panel {
		constructor(p = {}) {
			super(p);
			
		//	todo: rename this.node > this.datanode;
			this.node = new DataNode(p.data);
			
			
			this.style = Object.assign(this.style, {
				textAlign: 'left',
				textBaseline: 'top',
				font: '10px monospace',
				color: '#eeeeee'
			}, p.style || {});
		}
		
		get inPoint() { return this.globalPosition.add(0, this.globalSize.y/2); }
		get outPoint() { return this.globalPosition.add(this.globalSize.div(1, 2)); }
		
		draw(ctx) {
			super.draw(ctx);
			let style = this.style;
			
			let pos = this.globalPosition;
			let posp = pos.buf().add(style.padding);
			let size = this.globalSize;
			
		//	ctx.beginPath();
		//	ctx.rect(pos.x, pos.y, size.x, size.y);
		//	ctx.clip();
			
			ctx.save();
			ctx.rotateOffset(this.globalRotation, pos);
			
			ctx.beginPath();
			ctx.textBaseline = style.textBaseline;
			ctx.textAlign = 'center';
			ctx.fillStyle = '#33eeee';
			ctx.font = 'bold 12px monospace';
			ctx.fillText(this.name, pos.x+size.x/2, posp.y);
		//	'//===========['+
		//	+']===========//'
			
			ctx.textAlign = style.textAlign;
			ctx.fillStyle = style.color;
			ctx.font = style.font;
			
		//	this.node.inter.evaluate();
			
			ctx.fillText(`${'input'}`, posp.x, posp.y+15);
			ctx.fillText(`data: ${this.node.input.value}`, posp.x, posp.y+15*2);
			
			ctx.fillText(`${'output'}`, posp.x+70, posp.y+15);
			ctx.fillText(`data: ${this.node.output.value}`, posp.x+70, posp.y+15*2);
		}
		
		drawGUI(ctx) {
			let pos = this.globalPosition;
			let size = this.globalSize;
			ctx.save();
			ctx.beginPath();
			ctx.fillStyle = '#eeeeee';
			ctx.arc(pos.x, pos.y + size.y/2, cfg.radius, 0, Math.PI*2);
			ctx.rect(pos.x + size.x -cfg.radius, pos.y + size.y/2 -cfg.radius, cfg.radius*2, cfg.radius*2);
		//	ctx.arc(pos.x + size.x, pos.y + size.y/2, cfg.radius, 0, Math.PI*2);
			ctx.fill();
			ctx.restore();
		}
	};
};
